﻿using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.ServiceModel.Discovery;
using System.Timers;
using PIP.Shared;

namespace PIP.Worker
{
    public class Program
    {
        private static Timer NetScanTimer;

        static void Main()
        {
            Console.SetWindowPosition(0, 0);
            NetScanTimer = new Timer(1000);
            Console.WriteLine("{0} has started".With("Worker"));
            NetScanTimer.Elapsed += (sender, args) => Process();
            Process();

            Console.ReadKey();
        }
        static void Process()
        {
            Console.WriteLine("Scanning network...");
            NetScanTimer.Stop();
            var services = GetServices();
            if (services.IsNullOrEmpty())
                Console.WriteLine("No services found!");

            var filters = new AForge.Imaging.Filters.FiltersSequence();
            filters.Add(new AForge.Imaging.Filters.GaussianSharpen());
            filters.Add(new AForge.Imaging.Filters.GrayscaleBT709());

            foreach (var service in services)
            {
                try
                {
                    var pack = service.GetData();
                    while (pack != null)
                    {
                        foreach (var item in pack)
                        {
                            item.Data = filters.Apply(item.Data);
                            Console.WriteLine("Processed item with index {0}".With(item.Index));
                        }

                        service.PostData(pack);
                        pack = service.GetData();
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine("Service is down");
                }
            }
            NetScanTimer.Start();
        }

        private static IEnumerable<IServiceWork> GetServices()
        {
            var discoveryClient = new DiscoveryClient(new UdpDiscoveryEndpoint());
            var findCriteria = new FindCriteria(typeof(ServiceWork)) { Duration = TimeSpan.FromMilliseconds(1000) };
            var findResponse = discoveryClient.Find(findCriteria);

            var services = new List<IServiceWork>();
            var binding = new NetTcpBinding();
            binding.ReaderQuotas = new System.Xml.XmlDictionaryReaderQuotas() { MaxArrayLength = 67108864, MaxBytesPerRead = 67108864, MaxStringContentLength = 67108864 };

            binding.MaxReceivedMessageSize = 67108864;
            foreach (var serviceEndpoint in findResponse.Endpoints)
            {
                var factory = new ChannelFactory<IServiceWork>(binding, serviceEndpoint.Address);
                services.Add(factory.CreateChannel());
            }

            return services;
        }
    }
}